package com.example.license.service;

import com.example.license.entity.LicenseCheckModel;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author YangJian
 * @Description 用户获取服务器的硬件信息
 * @createTime 2022年03月25日 15:40
 */
@Slf4j
public abstract  class IAbstractServerInfos {
    private static final Pattern macPattern = Pattern.compile(".*((:?[0-9a-f]{2}[-:]){5}[0-9a-f]{2}).*",
            Pattern.CASE_INSENSITIVE);
    /**
     * 组装需要额外校验的License参数
     *
     * @return IpMaCInfo
     * @author chenhongjiao
     * @date 2021/03/26 14:23
     * @since 1.0.0
     */
    public LicenseCheckModel getServerInfos() {
        LicenseCheckModel result = new LicenseCheckModel();
        try {
            result.setIpAddress(this.getIpAddress());
            result.setMacAddress(this.getMacAddress());
        } catch (Exception e) {
            log.error("获取服务器硬件信息失败", e);
        }
        return result;
    }

    /**
     * @return java.util.List<java.lang.String>
     * @Description 获取IP地址
     * @Author YJ
     * @Date 2022/3/25 16:03
     * @Param []
     **/
    public abstract List<String> getIpAddress() throws Exception;

    /**
     * @return java.util.List<java.lang.String>
     * @Description 获取Mac地址
     * @Author YJ
     * @Date 2022/3/25 16:03
     * @Param []
     **/
    public abstract List<String> getMacAddress() throws Exception;

    /**
     * 获取当前服务器所有符合条件的InetAddress
     *
     * @return java.util.List<java.net.InetAddress>
     * @author YJ
     * @date 2022/03/26
     */
    protected List<InetAddress> getLocalAllInetAddress() throws Exception {
        List<InetAddress> result = new ArrayList<>(4);
        // 遍历所有的网络接口
        for (Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); networkInterfaces.hasMoreElements(); ) {
            NetworkInterface iface = (NetworkInterface) networkInterfaces.nextElement();
            //获取无线网卡的ip
            //if (iface.getDisplayName().contains(LicenseConstant.WIRELESS)) {
            // 在所有的接口下再遍历IP
            for (Enumeration inetAddresses = iface.getInetAddresses(); inetAddresses.hasMoreElements(); ) {
                InetAddress inetAddr = (InetAddress) inetAddresses.nextElement();
                //排除LoopbackAddress、SiteLocalAddress、LinkLocalAddress、MulticastAddress类型的IP地址
                if (!inetAddr.isLoopbackAddress()
                        && !inetAddr.isLinkLocalAddress() && !inetAddr.isMulticastAddress()) {
                    result.add(inetAddr);
                }
            }
            //}
        }
        return result;
    }

    /**
     * @description:windowns系统根据ip获取Mac地址
     * @param inetAddr
     * @return void
     * @author chenhongjiao
     * @date 2021/03/26 18:08
     * @since 1.0.0
     */
    protected String getWindownsMac(InetAddress inetAddr) {
        try {
            byte[] mac = NetworkInterface.getByInetAddress(inetAddr).getHardwareAddress();
            StringBuffer stringBuffer = new StringBuffer();
            for (int i = 0; i < mac.length; i++) {
                if (i != 0) {
                    stringBuffer.append("-");
                }
                //将十六进制byte转化为字符串
                String temp = Integer.toHexString(mac[i] & 0xff);
                if (temp.length() == 1) {
                    stringBuffer.append("0" + temp);
                } else {
                    stringBuffer.append(temp);
                }
            }
            return stringBuffer.toString().toUpperCase();
        } catch (SocketException e) {
            log.error(e.getMessage());
        }
        return null;
    }
    protected List<String> getLinuxMacInfo(String[] server) throws IOException {
        List<String> result = new ArrayList<>();
        // 执行命令
        final Process process = Runtime.getRuntime().exec(server);
        BufferedReader bufReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        for (String line = null; (line = bufReader.readLine()) != null;) {
            Matcher matcher = macPattern.matcher(line);
            if (matcher.matches()) {
                result.add(matcher.group(1));
                // macAddressList.add(matcher.group(1).replaceAll("[-:]",
                // ""));//去掉MAC中的“-”
            }
        }
        process.destroy();
        bufReader.close();
        return result.stream().distinct().collect(Collectors.toList());
    }
    /**
     * @description:Linux系统获取单个网卡地址
     * @param
     * @return java.lang.String
     * @author YangJian
     * @date 2022/4/15 11:58
     */
    protected String getLinuxMac(){
        String macAddress = null;
        String command="cat /sys/class/net/eth0/address";
        String str = "";
        try {
            //linux下查询网卡mac地址的命令
            Process pp = Runtime.getRuntime().exec(command);
            InputStreamReader ir = new InputStreamReader(pp.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);

            for (; null != str; ) {
                str = input.readLine();
                if (str != null) {
                    macAddress = str.trim();// 去空格
                    break;
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return macAddress;
    }
}
